from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from .models import BookModel, Publish, Author, Stuff, Salary


# class BookSerializer(serializers.Serializer):
#     title = serializers.CharField(max_length=3)
#     price = serializers.IntegerField()
#
#     # pub_date = serializers.DateField()
#
#     # 重写create方法，写入数据库，让序列化器对象可以调用save方法
#     def create(self, validated_data):
#         obj = BookModel.objects.create(**self.validated_data)
#         return obj
#
#     def update(self, instance, validated_data):
#         # 更新数据
#         BookModel.objects.filter(pk=instance.pk).update(**validated_data)
#         # 获修改后的实例对象，返回修改后的序列化对象
#         self.instance = BookModel.objects.get(pk=instance.pk)
#         return self.instance

# 模型序列化
class BookSerializer(serializers.ModelSerializer):
    # 只需要关联这个表模型 就可以实现字段对应的序列化器

    # 如果需要针对某个字段重命名操作可以单独在写一行
    sale_price = serializers.IntegerField(source="price")

    class Meta:
        model = BookModel
        # 默认是显示所有字段,也可以用fields = __all__, 或者指定某些字段显示 fields = ['field1', 'field2', '..']
        # fields = ['title','sale_price']
        # 排除某些字段
        exclude = ['price']


class BookView(APIView):
    def get(self, request):
        # 获取数据库所有数据库所有数
        book_list = BookModel.objects.all()
        # # 序列化
        serializer = BookSerializer(instance=book_list, many=True)
        return Response(serializer.data)

    # 插入数据
    def post(self, request):
        # 获取响应体数据,并进行反序列化
        serializer = BookSerializer(data=request.data)
        # 对数据进行校验，校验通过则返回数据，校验不通过则返回错误信息
        if serializer.is_valid():
            # 校验通过写入数据库
            # BookModel.objects.create(**serializer.validated_data)
            serializer.save()
            # return Response(serializer.data)
            return JsonResponse({'code': 200, 'msg': 'ok', 'data': serializer.data})
        else:
            return Response(serializer.errors)


class BookDetailView(APIView):
    # 获取单条记录
    def get(self, request, pk):
        book = BookModel.objects.get(pk=pk)  # 模型对象
        # 序列化
        serializer = BookSerializer(instance=book, many=False)
        return Response(serializer.data)

    # 编辑单条数据库记录
    def put(self, request, pk):
        # 获取需要编辑的数据的模型对象
        book = BookModel.objects.get(pk=pk)
        # 获取传入的编辑数据库记录
        update_data = request.data
        # 反序列化
        serializer = BookSerializer(instance=book, data=update_data)
        # 对数据进行校验
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)  # 返回编辑后的数据
        else:
            return Response(serializer.errors)

    def delete(self, request, pk):
        BookModel.objects.get(pk=pk).delete()
        return Response("ok")


# --------------------------GenericApiView----------------------------------
from rest_framework.generics import GenericAPIView


class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = Publish
        fields = "__all__"


class PublishGenericAPIView(GenericAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request):
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)
        return Response(serializer.data)

    def post(self, request):
        # 获取响应体数据,并进行反序列化
        serializer = self.get_serializer(data=request.data)
        # 对数据进行校验，校验通过则返回数据，校验不通过则返回错误信息
        if serializer.is_valid():
            # 校验通过写入数据库
            # BookModel.objects.create(**serializer.validated_data)
            serializer.save()
            # return Response(serializer.data)
            return JsonResponse({'code': 200, 'msg': 'ok', 'data': serializer.data})
        else:
            return Response(serializer.errors)


class PublishDetailView(GenericAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer

    def get(self, request, pk):
        # 获取单个对象，需要在url中写上有名分组
        serializer = self.get_serializer(instance=self.get_object(), many=False)
        return Response(serializer.data)

    # 编辑单条记录
    def put(self, request, pk):
        serializer = self.get_serializer(instance=self.get_object(), data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = "__all__"


class AuthorGenericAPIView(GenericAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

    def get(self, request):
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)
        return Response(serializer.data)

    def post(self, request):
        # 获取响应体数据,并进行反序列化
        serializer = self.get_serializer(data=request.data)
        # 对数据进行校验，校验通过则返回数据，校验不通过则返回错误信息
        if serializer.is_valid():
            # 校验通过写入数据库
            # BookModel.objects.create(**serializer.validated_data)
            serializer.save()
            # return Response(serializer.data)
            return JsonResponse({'code': 200, 'msg': 'ok', 'data': serializer.data})
        else:
            return Response(serializer.errors)


class AuthorDetailView(GenericAPIView):
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

    def get(self, request, pk):
        # 获取单个对象，需要在url中写上有名分组
        serializer = self.get_serializer(instance=self.get_object(), many=False)
        return Response(serializer.data)

    # 编辑单条记录
    def put(self, request, pk):
        serializer = self.get_serializer(instance=self.get_object(), data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


# -------------------------------------------------------MinIN混合类接口实现----------------------------------

from rest_framework.mixins import ListModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    CreateModelMixin


class StuffSerializer(serializers.ModelSerializer):
    class Meta:
        model = Stuff
        fields = "__all__"


class StuffMinInView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Stuff.objects.all()
    serializer_class = StuffSerializer

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)


class StuffMinInDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Stuff.objects.all()
    serializer_class = StuffSerializer

    def get(self, request, pk):
        # 获取单个对象，需要在url中写上有名分组
        return self.retrieve(request, pk)

    # 编辑单条记录
    def put(self, request, pk):
        return self.update(request, pk)

    def delete(self, request, pk):
        return self.destroy(request, pk)


# ----------------------------------Minin混合类的再封装----------------------------------------------

# from rest_framework.generics import ListCreateAPIView,RetrieveUpdateDestroyAPIView,RetrieveAPIView
# class StuffMinInView(ListCreateAPIView):
#     queryset = Stuff.objects.all()
#     serializer_class = StuffSerializer
#
# # 只需要查看单条记录的话 可以只继承RetrieveAPIView
# class StuffMinInDetailView(RetrieveUpdateDestroyAPIView):
#     queryset = Stuff.objects.all()
#     serializer_class = StuffSerializer

# -----------------------------ViewSet :对请求方式分发的重新构建-----------------------------------------------

# from rest_framework.viewsets import ViewSet
#
#
# class SalarySerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Salary
#         fields = "__all__"
#
#
# class SalaryViewSet(ViewSet):
#     # 将所有的请求都写在一个类下面
#     def get_all(self, request):
#         return Response("查看所有数据")
#
#     def create_data(self, request):
#         return Response("添加数据")
#
#     def get_single_data(self, request, pk):
#         return Response("查看单条数据")
#
#     def update_data(self, request, pk):
#         return Response("更新数据")
#
#     def delete_data(self, request, pk):
#         return Response("删除数据")


# 上述 需要配合generic视图类，和minin混合类来进行代码的优化
from rest_framework.viewsets import GenericViewSet, ModelViewSet


class SalarySerializer(serializers.ModelSerializer):
    class Meta:
        model = Salary
        fields = "__all__"


# class SalaryViewSet(GenericViewSet, ListModelMixin, CreateModelMixin, RetrieveModelMixin, DestroyModelMixin,UpdateModelMixin):
#     # 如果引用了minin混合类，需要将url中请求方式的映射换位该类中的方法映射，即list、create、等
#     queryset = Salary.objects.all()
#     serializer_class = SalarySerializer

# ------------------------------------------------ModelViewSet -----------------------------------------------------
class SalaryViewSet(ModelViewSet):
    # 如果引用了minin混合类，需要将url中请求方式的映射换位该类中的方法映射，即list、create、等
    queryset = Salary.objects.all()
    serializer_class = SalarySerializer

# 虽然方便快捷，但是针对不同情况还需要做不同选择，选择不同的视图类，以适应更多的业务需求
